package com.ysd.lis.service.view.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ysd.common.Result;
import com.ysd.lis.entity.SysUser;
import com.ysd.lis.entity.view.ViewApplyInfo;
import com.ysd.lis.entity.view.ViewApplyInfoLog;
import com.ysd.lis.mapper.view.ViewApplyInfoMapper;
import com.ysd.lis.request.DeleteParam;
import com.ysd.lis.service.lab.impl.LabReqMainBacServiceImpl;
import com.ysd.lis.service.view.ViewApplyInfoLogService;
import com.ysd.lis.service.view.ViewApplyInfoService;
import com.ysd.util.RedisUserManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author wanghuaixing
 * @since 2024-09-10
 */
@Service
public class ViewApplyInfoServiceImpl extends ServiceImpl<ViewApplyInfoMapper, ViewApplyInfo> implements ViewApplyInfoService {

    private static final Logger logger = LoggerFactory.getLogger(ViewApplyInfoServiceImpl.class);

    @Autowired
    ViewApplyInfoService viewApplyInfoService;
    @Autowired
    private DataSource dataSource;
    @Autowired
    private ViewApplyInfoLogService viewApplyInfoLogService;

    @Override
    public Result getViewApplyList(ViewApplyInfo viewApplyInfo) {
        LambdaQueryWrapper<ViewApplyInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.and(StrUtil.isNotEmpty(viewApplyInfo.getKeyword()), p -> p.like(ViewApplyInfo::getName, viewApplyInfo.getKeyword()).or().like(ViewApplyInfo::getTitle, viewApplyInfo.getKeyword()))
                .eq(ViewApplyInfo::getDelFlag, 0)
                .eq(StrUtil.isNotEmpty(viewApplyInfo.getViewSource()), ViewApplyInfo::getViewSource, viewApplyInfo.getViewSource())
                .eq(StrUtil.isNotEmpty(viewApplyInfo.getViewType()), ViewApplyInfo::getViewType, viewApplyInfo.getViewType())
                .orderByDesc(ViewApplyInfo::getCreateTime);
        return Result.succ(1, "查询成功", viewApplyInfoService.list(lambdaQueryWrapper));
    }

    @Override
    public Result auditViews(DeleteParam deleteParam) {
        String ids = deleteParam.getIds();
        String[] split = ids.split(",");
        SysUser sysUser = RedisUserManager.getUser();
        LambdaQueryWrapper<ViewApplyInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(ViewApplyInfo::getId, split).eq(ViewApplyInfo::getDelFlag, 0);
        List<ViewApplyInfo> list = viewApplyInfoService.list(lambdaQueryWrapper);
        list.forEach(a -> {
            String sql = "CREATE  VIEW  " + a.getName() + " AS " + a.getContent();
            try {
                Db.use(dataSource).execute(sql);
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
            //审核
            a.setStatus(1);
            a.setAuditer(sysUser.getUsername());
            a.setAuditName(sysUser.getRealname());
            a.setAuditTime(Timestamp.valueOf(LocalDateTime.now()));
            viewApplyInfoService.updateById(a);
        });
        return Result.succ(1, "审核成功", "");
    }

    @Override
    public Result getViewApplyTestResultList(ViewApplyInfo viewApplyInfo) throws SQLException {
        Map map = new HashMap();
        String sqls = viewApplyInfo.getSql().toUpperCase(Locale.ROOT);
        if (sqls.contains("CREATE")) {
            sqls = sqls.substring(sqls.indexOf("SELECT"));
        }
        logger.info("开始执行视图语句" + sqls);
        long l = System.currentTimeMillis();
        List<Entity> query = Db.use(dataSource).query(sqls);
        long e = System.currentTimeMillis();
        logger.info("执行时间：" + (e - l));
        viewApplyInfo.setCostTime((e - l) + "ms");
        viewApplyInfoService.updateById(viewApplyInfo);
        //插入日志
        SysUser  sysUser = RedisUserManager.getUser();
        ViewApplyInfoLog viewApplyInfoLog = new ViewApplyInfoLog();
        viewApplyInfoLog.setExecutor(sysUser.getUsername());
        viewApplyInfoLog.setExecutName(sysUser.getRealname());
        viewApplyInfoLog.setExecutTime(Timestamp.valueOf(LocalDateTime.now()));
        viewApplyInfoLog.setCostTime((e - l)+"");
        viewApplyInfoLog.setSystemName("LIS");
        viewApplyInfoLog.setName(viewApplyInfo.getName());
        viewApplyInfoLogService.save(viewApplyInfoLog);
        if (CollectionUtils.isNotEmpty(query)) {
            map.put("data", query);
            map.put("coloums", query.get(0).keySet());
            return Result.succ(1, "执行成功", map);
        }
        return Result.succ(1, "执行成功", "");
    }

    @Override
    public Result saveViewApplyInfo(ViewApplyInfo viewApplyInfo) {
        SysUser sysUser = RedisUserManager.getUser();
        viewApplyInfo.setApplyer(sysUser.getUsername());
        viewApplyInfo.setApplyName(sysUser.getRealname());
        viewApplyInfo.setApplyTime(Timestamp.valueOf(LocalDateTime.now()));
        boolean save = viewApplyInfoService.saveOrUpdate(viewApplyInfo);
        if (save) {
            return Result.succ(1, "保存成功", "");
        }
        return Result.fail("保存失败");
    }

    @Override
    public Result deleteViewApplyInfo(ViewApplyInfo viewApplyInfo) {
        return null;
    }

    @Override
    public Result getViewApplyDataSourceList(ViewApplyInfo viewApplyInfo) throws SQLException {
        if ("1".equals(viewApplyInfo.getFlag())) {
            //执行轮询插入数据库黑户视图
            String sql = "\n" +
                    "SELECT \n" +
                    "  v.object_id as id,  v.name as name ,v.create_date as createTime,v.modify_date as editTime,m.definition as content \n" +
                    "FROM \n" +
                    "    sys.views v\n" +
                    "INNER JOIN \n" +
                    "    sys.sql_modules m ON v.object_id = m.object_id";
            List<Entity> query = Db.use(dataSource).query(sql);
            List<ViewApplyInfo> lists = new ArrayList<>();
            for (Entity entity : query) {
                ViewApplyInfo viewApplyInfo11 = new ViewApplyInfo();
                viewApplyInfo11.setId(entity.get("id") + "");
                viewApplyInfo11.setName((String) entity.get("name"));
                String content = entity.getStr("content");
                viewApplyInfo11.setContent(content);
                viewApplyInfo11.setViewSource("1");
                viewApplyInfo11.setViewType("1");
                viewApplyInfo11.setStatus(1);
                viewApplyInfo11.setApplyTime((Timestamp) entity.get("createTime"));
                lists.add(viewApplyInfo11);
            }
            viewApplyInfoService.saveOrUpdateBatch(lists);
        }
        LambdaQueryWrapper<ViewApplyInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.and(StrUtil.isNotEmpty(viewApplyInfo.getKeyword()), p -> p.like(ViewApplyInfo::getName, viewApplyInfo.getKeyword()).or().like(ViewApplyInfo::getTitle, viewApplyInfo.getKeyword()))
                .eq(ViewApplyInfo::getDelFlag, 0)
                .eq(StrUtil.isNotEmpty(viewApplyInfo.getViewSource()), ViewApplyInfo::getViewSource, viewApplyInfo.getViewSource())
                .eq(StrUtil.isNotEmpty(viewApplyInfo.getViewType()), ViewApplyInfo::getViewType, viewApplyInfo.getViewType())
                .orderByDesc(ViewApplyInfo::getCreateTime);
        return Result.succ(1, "查询成功", viewApplyInfoService.list(lambdaQueryWrapper));
    }

    @Override
    public Result closeViewApplyDataSourceList(ViewApplyInfo viewApplyInfo) throws SQLException {
        SysUser sysUser = RedisUserManager.getUser();
        String sql = "DROP  VIEW  " + viewApplyInfo.getName();
        try {
            Db.use(dataSource).execute(sql);
        } catch (SQLException throwables) {
            return Result.succ(400, "关闭失败", throwables.getMessage());
        }
        viewApplyInfo.setStatus(3);
        viewApplyInfo.setCloser(sysUser.getUsername());
        viewApplyInfo.setCloseName(sysUser.getRealname());
        viewApplyInfo.setCloseTime(Timestamp.valueOf(LocalDateTime.now()));
        viewApplyInfoService.updateById(viewApplyInfo);
        return Result.succ(1, "关闭成功", "");
    }
    @Override
    public Result openViewApplyDataSourceList(ViewApplyInfo viewApplyInfo) throws SQLException {
        SysUser sysUser = RedisUserManager.getUser();
        String sql = viewApplyInfo.getContent();
        try {
            Db.use(dataSource).execute(sql);
        } catch (SQLException throwables) {
            return Result.succ(400, "开启失败", throwables.getMessage());
        }
        //审核
        viewApplyInfo.setStatus(1);
        viewApplyInfo.setCloser(sysUser.getUsername());
        viewApplyInfo.setCloseName(sysUser.getRealname());
        viewApplyInfo.setCloseTime(Timestamp.valueOf(LocalDateTime.now()));
        viewApplyInfoService.updateById(viewApplyInfo);
        return Result.succ(1, "开启成功", "");
    }

    @Override
    public Result getViewLogByName(ViewApplyInfo viewApplyInfo){
        List<ViewApplyInfoLog> list = viewApplyInfoLogService.list(new LambdaQueryWrapper<ViewApplyInfoLog>().eq(ViewApplyInfoLog::getName, viewApplyInfo.getName()).orderByDesc(ViewApplyInfoLog::getCreateTime));
        return Result.succ(1, "查询成功", list);
    }
}
